查看原文
其他

Android AutoWrapTextView 解决中英文排版问题

伪文艺大叔 鸿洋 2019-04-05

每日推荐


就在昨天Github小伙伴们,发布了【Android源码解析开源项目:难产的7篇】,这一期隔了相当久,默默的支持下:



https://github.com/LittleFriendsGroup/AndroidSdkSourceAnalysis/blob/master/README.md


本文作者


本文由伪文艺大叔投稿。

伪文艺大叔的博客地址:

http://www.jianshu.com/u/030d732a71d2


1
概述

最近项目有新需求,UED给了个卡券密码的UI样式,如图:





我一看很简单啊,一个TextView解决问题,然后做好以后在模拟器里一看.....




纳尼,这个时候才想起来,TextView 中英文在一起会有排版问题,那怎么解决呢......


思路


刚开始的想法是一个字符一个字符的去绘制,绘制到最右边的临界点就换行绘制,结果实践以后发现不同的字符之间的间距不一样,显示会非常凌乱,又没有什么好的方案解决这个间距问题,所以这个方案pass;


单个字符绘制不行那就一行一行绘制,根据View的长度把文本拆分成N行,然后一行一行的绘制。


2
实现

首先创建一个继承自View的AutoWrapTextView


init方法里分别调用了initStyle方法和initPaint方法;


initStyle方法主要解析自定义的属性



属性名含义都很明显不用过多解释,initPaint方法就是初始化一个文本画笔



接下来我们看看设置文本的方法setText方法



首先把文本转换成Char数组,然后循环数组把整个文本拆分成N行文本,下面来看看核心方法splitText方法



首先创建一个属性名为mSplitTextList的List集合用来存放拆分的文本;
mSingleTextWidth 为单行文本显示的宽度;


currentSingleTextWidth 为当前一行累计计算的宽度;


然后开始循环Char数组,getSingleCharWidth方法就是计算单个Char的宽度;
如果currentSingleTextWidth 小于 mSingleTextWidth 就把Char添加到lineStringBuffer 当中,如果是最后一个Char就直接把lineStringBuffer添加到mSplitTextList集合当中


如果currentSingleTextWidth 大于 mSingleTextWidth,就把lineStringBuffer添加到mSplitTextList集合当中,重新给lineStringBuffer赋值,currentSingleTextWidth 归0;


循环结束以后拆分好的文本就都添加到mSplitTextList集合当中了。

拆分完成以后循环mSplitTextList集合,得到每一行文本的Rect值,绘制文本的时候会用到,然后设置View的宽高。


接下来就是绘制方法drawText



首先得到第一行文本距离顶部的高度marginTop,然后循环文本绘制每一行文本内容。


效果图


我们来看下最后的效果




至此整个类的逻辑分析就结束了,想看完整源码的可以移步:

https://github.com/chenpengfei88/AutoWrapTextView


欢迎大家Star,Follow。

ZZS

无论你是有 Java 基础希望学 Android 开发的程序员,还是想进一步提升能力的 Android 开发者,都可以在这个Udacity & Google 官方参与制作 的课程项目中找到适合自己的成长路径!



*独家硅谷技术课程

*行业领导者设计的实战项目

*一对一学习辅导

*名企颁发学习认证

*毕业直达滴滴面试


如果你有想学习的文章直接留言,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我投递文章链接即可。


欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号:

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存